package org.yu.team2023.flashdays.entity;

import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.stats.Stats;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.network.NetworkHooks;
import net.minecraftforge.network.PacketDistributor;
import org.jetbrains.annotations.NotNull;
import org.yu.team2023.flashdays.FDConfig;
import org.yu.team2023.flashdays.ModUtil;
import org.yu.team2023.flashdays.net.DamageParticlePackage;
import org.yu.team2023.flashdays.net.FlashNet;
import software.bernie.geckolib.animatable.GeoEntity;
import software.bernie.geckolib.constant.DefaultAnimations;
import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.core.animation.AnimatableManager;
import software.bernie.geckolib.core.animation.AnimationController;
import software.bernie.geckolib.core.object.PlayState;
import software.bernie.geckolib.util.GeckoLibUtil;

import java.util.List;
import java.util.stream.Stream;

public class DamageHuman extends Mob implements GeoEntity {
    private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
    public DamageHuman(EntityType<? extends Mob> pEntityType, Level pLevel) {
        super(pEntityType, pLevel);
    }
    public static AttributeSupplier.Builder createAttributes() {
        return Mob.createMobAttributes().add(Attributes.MAX_HEALTH,16384).add(Attributes.KNOCKBACK_RESISTANCE,1);
    }


    @Override
    public void setDeltaMovement(Vec3 pDeltaMovement) {

    }

    @Override
    public boolean canBeCollidedWith() {
        return this.isAlive();
    }

    @Override
    public Packet<ClientGamePacketListener> getAddEntityPacket() {
        return NetworkHooks.getEntitySpawningPacket(this);
    }

    @Override
    public boolean isNoGravity() {
        return true;
    }

    @Override
    public boolean hurt(DamageSource pSource, float pAmount) {
        boolean ret= super.hurt(pSource, pAmount);
        this.invulnerableTime=0;
        return ret;
    }

    @Override
    public InteractionResult interactAt(Player pPlayer, Vec3 pVec, InteractionHand pHand) {
        if(pPlayer.getAbilities().instabuild&&pPlayer.isShiftKeyDown()) {
            setRemoved(RemovalReason.DISCARDED);
            return InteractionResult.SUCCESS;
        }
        return super.interactAt(pPlayer, pVec, pHand);
    }

    @Override
    public void registerControllers(AnimatableManager.ControllerRegistrar registrar) {
        registrar.add(DefaultAnimations.getSpawnController(this, s->this,40));
        registrar.add(genericIdleController());
    }
    private   AnimationController<DamageHuman> genericIdleController() {
        return new AnimationController<>(this, "Idle", 10, state -> {
            if (isAlive())
                return state.setAndContinue(DefaultAnimations.IDLE);
            return PlayState.STOP;
        });
    }



    @Override
    public AnimatableInstanceCache getAnimatableInstanceCache() {
        return cache;
    }

    @Override
    public void tick() {
        super.tick();
    }
    String msgs= """
            真是让人叹为观止，你的拳击功夫堪比慢动作电影。
            打得这么温柔，我差点以为你是来和我牵手的呢。
            别害怕，我对昆虫是没有免疫力的，你的拳头像只有蚊子那么可怕。
            我猜你是学了‘无伤拳’，因为连我皮都没打破。
            这样的拳法，你练得是不是‘减肥拳’？连我都觉得减轻体重了。
            别生气，你的拳击技巧至少对于小狗来说还是挺可怕的。
            听说你的绰号是‘柔风拳王’，果然名不虚传，像微风拂面一样温柔。
            我很欣赏你的勇气，毕竟拳击场上要有表演者，才能凸显出我的英勇。
            别太沮丧，至少你可以在儿童乐园里找份工作，给小朋友示范如何打气球。
            我感觉你的打击对我就跟喂小鸟扔面包屑一样，轻飘飘的，几乎没有感觉。
            你的拳法像个小绵羊在拍打，还挺可爱的。
            打击效果有点差，我都差点忘记是在拳击场上。
            别灰心，至少你可以在街头艺人中拥有一席之地。
            我之前没说清楚，我可是练过‘铁头功’的，你的拳头才不够硬呢。
            你的拳击速度让我想起了龟速比赛，你应该有出色的表现。
            打击之前记得踩踩地，不然像现在这样像个跳舞的。
            我猜你的拳击教练是个魔术师，把你的实力变得无影无踪了吧。
            别怕，你的拳法适合去照顾老年人，保证不会伤到他们。
            你的拳击姿势有点像在抓小白鼠，我都忍不住给你递个奶酪了。
            我知道你在练‘幽灵拳’，可惜对我完全没用，我不信鬼神。
            你的拳击像小朋友在玩捉迷藏，让我找不到击打的感觉。
            听说你是从瑜伽界转战拳击场，难怪你的动作都那么柔和。
            别灰心，至少你的拳击让我笑出了腹肌锻炼。
            我感觉你的拳击就像夏天的微风，根本无法吹倒我。
            打击效果有点像蚊子叮咬，几乎没有感觉。
            你这招是在练‘悠闲拳’吗？我都有点想打个盹了。
            我看你的拳击水平，最多只能吓退一只猫而已。
            你的拳法像小猫抓纸，轻飘飘一点力道都没有。
            别紧张，你的拳头像小松鼠在捶胸口，毛茸茸的没用处。
            我觉得你的拳击更适合在搏击游戏里扮演NPC，给玩家增加成就感。
            你的剑法像是在做花样游泳，优雅而没有威胁性。
            用剑的时候记得不要割到自己，否则伤口可不好看。
            你这样的剑术，大概连挑菜刀都不如吧。
            我曾听说过舞剑的，但没想到你的剑法是舞花拂柳吧？
            你用剑的样子，让我觉得像在看一出悲情古装戏。
            剑在你手里，更像是一件装饰品，而不是杀伐之器。
            别怕，即便是木剑，你也可以去教授少林寺的小和尚们了。
            用剑时不要太拘泥，动作要自然，就像在挥舞彩虹一样。
            剑术不好，没关系，总有些人适合当和平使者，你就是其中之一。
            你的剑招像是来给我挠痒痒的，有没有更刺激的动作呢？
            你的武器舞技让我想起了滑稽戏里的魔术师。
            用武器时不要太急躁，要像优雅的舞者一样，悠然自得。
            你手里的武器像是摆设，对我一点威胁都没有。
            我感觉你的武器技巧更适合去驱赶苍蝇，让它们远离餐桌。
            你的武器动作太过夸张，我都差点以为你在演喜剧表演。
            用武器要灵活多变，可你的动作看起来像是生锈了。
            别气馁，至少你的武器舞姿给我提供了欢乐的笑料。
            你这样的武器运用，大概连蔬菜刀都不如吧。
            我听说过舞刀的，但没想到你的武器舞蹈风格这么独特。
            你用武器时的样子，像是在跟无形的敌人较劲，好戏连台。
            你的武器舞技让我想起了滑稽戏里的魔术师。
            用武器时不要太急躁，要像优雅的舞者一样，悠然自得。
            你手里的武器像是摆设，对我一点威胁都没有。
            我感觉你的武器技巧更适合去驱赶苍蝇，让它们远离餐桌。
            你的武器动作太过夸张，我都差点以为你在演喜剧表演。
            用武器要灵活多变，可你的动作看起来像是生锈了。
            别气馁，至少你的武器舞姿给我提供了欢乐的笑料。
            你这样的武器运用，大概连蔬菜刀都不如吧。
            我听说过舞刀的，但没想到你的武器舞蹈风格这么独特。
            你用武器时的样子，像是在跟无形的敌人较劲，好戏连台。
            用武器的时候别忘了保持微笑，你的表情跟杀气完全不搭。
            我建议你参加《世界搞笑杂技大赛》，你的武器技巧绝对称得上杂技高手。
            你这样的武器舞姿，不如去参加《飞刀大赛》，给自己开个新的发展方向吧。
            别看你手里握着武器，动作却像在给花儿拥抱。
            用武器时别忘了发出声音，哇哦，听说你的武器练成了“哑剑”。
            你的武器技巧让我想起了一出闹剧，不知道下一幕是什么笑料。
            看你的武器动作，我都怀疑你是在跳刀舞。
            你这样的武器技巧，最多适合在农村搞个村民武术表演团。
            用武器时要像舞者一样从容优雅，你的动作像个蹩脚跳舞的熊孩子。
            你用武器的样子像是在拿着毛笔在画空气，挥来挥去毫无章法。
            你这样的武器运用，至少能给敌人提供个搞笑片段。
            你的武器技巧像是在给我展示一个剑舞泡泡的节目。
            用武器时要像个大侠，可你更像个失足青年。
            看你的武器舞姿让我想起了小学生的体操表演。
            用武器时要学会点戏剧表演，你的动作有点太生硬。
            你的武器动作就像个晃晃悠悠的风车，让我有点晕眩。
            用武器时别像在画天线宝宝，要霸气凌人才行。
            你的武器舞姿像是在跟无形的蚊子打架。
            """;
    List<String> msgList= Stream.of(msgs.split("\n")).toList();
    @Override
    protected void actuallyHurt(@NotNull DamageSource pDamageSource, float damage) {
        float pDamageAmount = net.minecraftforge.common.ForgeHooks.onLivingHurt(this, pDamageSource, damage);
        if (pDamageAmount <= 0) return;
        pDamageAmount = this.getDamageAfterArmorAbsorb(pDamageSource, pDamageAmount);
        pDamageAmount = this.getDamageAfterMagicAbsorb(pDamageSource, pDamageAmount);
        float finalDamage = Math.max(pDamageAmount - this.getAbsorptionAmount(), 0.0F);
        this.setAbsorptionAmount(this.getAbsorptionAmount() - (pDamageAmount - finalDamage));
        float f = pDamageAmount - finalDamage;
        Entity entity = pDamageSource.getEntity();
        if (entity instanceof ServerPlayer serverplayer) {
            serverplayer.awardStat(Stats.DAMAGE_DEALT_ABSORBED, Math.round(f * 10.0F));
            if(FDConfig.SHOW_ANNOUNCE )
            serverplayer.displayClientMessage(Component.literal(ModUtil.randomSelect(msgList)), false);
        }
       Component result =finalDamage==Double.POSITIVE_INFINITY?Component.translatable("damage.POSITIVE_INFINITY"):Component.literal(String.format("%.0f", finalDamage));
        ModUtil.findAllPlayersNearby(player -> {
            var pkg=DamageParticlePackage.formEntity(this,result,pDamageSource);
            var bbh=getBbHeight();
            if(bbh>1) {
                pkg.setScale(-bbh);
                pkg.move(0,bbh/2d,0);
            }
            FlashNet.channel.send(PacketDistributor.PLAYER.with(
                            () -> player
                    ),pkg
            );
        }, this, 64);
    }

    @Override
    public void heal(float pHealAmount) {
        super.heal(pHealAmount);
        super.setHealth(getMaxHealth()/2f);
    }

    @Override
    public void setHealth(float pHealth) {
        super.setHealth(getMaxHealth()/2f);
    }
}
